#include "AnimatedSprite.h"

#include <stdio.h>
#include <cassert>


AnimatedSprite::AnimatedSprite(sf::Texture* texture, sf::Int32 sourceX, sf::Int32 sourceY, sf::Int32 width, sf::Int32 height, sf::Int32 fps, sf::Int32 numFrames, bool looped)
: m_texture(texture)
, m_sprite(NULL)
, m_sourceX(sourceX)
, m_sourceY(sourceY)
, m_width(width)
, m_height(height)
, m_looped(looped)
, m_frameTime(1000 / fps)
, m_numFrames(numFrames + (looped ? (numFrames - 2) : 0))
, m_elapsedTime(0)
, m_currentFrame(0)
{
    assert(texture);
    assert(m_numFrames > 0);

    m_sourceRect.reserve(m_numFrames);
    if(!looped)
    {
        for(sf::Int32 i = 0; i < m_numFrames; ++i)
        {
            sf::IntRect rect(m_sourceX + (m_width * i), m_sourceY, m_width, m_height);
            m_sourceRect.push_back(rect);
        }
    }
    else // looped
    {
        for(sf::Int32 i = 0; i < m_numFrames; ++i)
        {
            sf::IntRect rect;
            if(i < numFrames)
            {
                rect = sf::IntRect(m_sourceX + (m_width * i), m_sourceY, m_width, m_height);
            }
            else
            {
                const sf::Int32 index = (2 * numFrames) - i - 2; // believe
                rect = sf::IntRect(m_sourceX + (m_width * index), m_sourceY, m_width, m_height);
            }

            m_sourceRect.push_back(rect);
        }
    }

    m_sprite = new sf::Sprite(*m_texture);
    if(!m_sprite)
    {
        printf("Failed to create sprite\n");
        return; // Is this nice?
    }

    m_sprite->setTextureRect(m_sourceRect[0]);
}

AnimatedSprite::~AnimatedSprite()
{
    delete m_sprite;
}

void AnimatedSprite::Draw(sf::RenderWindow& window) const
{
    window.draw(*m_sprite);
}

void AnimatedSprite::Update(sf::Int32 elapsed_time_ms)
{
    if(elapsed_time_ms == 0)
    {
        return;
    }

    m_sprite->setPosition(320.f, 320.f);

    m_elapsedTime += elapsed_time_ms;
    if(m_elapsedTime > m_frameTime)
    {
        ++m_currentFrame;
        m_elapsedTime = 0;
        if(m_currentFrame >= m_numFrames)
        {
            m_currentFrame = 0;
        }

        m_sprite->setTextureRect(m_sourceRect[m_currentFrame]);
    }
}
